<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en"><head><title>Implementers' Draft: OAuth Request Body Hash 1.0 Draft 5</title>
<meta http-equiv="Expires" content="Mon, 30 Mar 2009 06:40:12 +0000">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="description" content="OAuth Request Body Hash 1.0 Draft 5">
<meta name="generator" content="xml2rfc v1.33 (http://xml.resource.org/)">
<style type='text/css'><!--
        body {
                font-family: verdana, charcoal, helvetica, arial, sans-serif;
                font-size: small; color: #000; background-color: #FFF;
                margin: 2em;
        }
        h1, h2, h3, h4, h5, h6 {
                font-family: helvetica, monaco, "MS Sans Serif", arial, sans-serif;
                font-weight: bold; font-style: normal;
        }
        h1 { color: #900; background-color: transparent; text-align: right; }
        h3 { color: #333; background-color: transparent; }

        td.RFCbug {
                font-size: x-small; text-decoration: none;
                width: 30px; height: 30px; padding-top: 2px;
                text-align: justify; vertical-align: middle;
                background-color: #000;
        }
        td.RFCbug span.RFC {
                font-family: monaco, charcoal, geneva, "MS Sans Serif", helvetica, verdana, sans-serif;
                font-weight: bold; color: #666;
        }
        td.RFCbug span.hotText {
                font-family: charcoal, monaco, geneva, "MS Sans Serif", helvetica, verdana, sans-serif;
                font-weight: normal; text-align: center; color: #FFF;
        }

        table.TOCbug { width: 30px; height: 15px; }
        td.TOCbug {
                text-align: center; width: 30px; height: 15px;
                color: #FFF; background-color: #900;
        }
        td.TOCbug a {
                font-family: monaco, charcoal, geneva, "MS Sans Serif", helvetica, sans-serif;
                font-weight: bold; font-size: x-small; text-decoration: none;
                color: #FFF; background-color: transparent;
        }

        td.header {
                font-family: arial, helvetica, sans-serif; font-size: x-small;
                vertical-align: top; width: 33%;
                color: #FFF; background-color: #666;
        }
        td.author { font-weight: bold; font-size: x-small; margin-left: 4em; }
        td.author-text { font-size: x-small; }

        /* info code from SantaKlauss at http://www.madaboutstyle.com/tooltip2.html */
        a.info {
                /* This is the key. */
                position: relative;
                z-index: 24;
                text-decoration: none;
        }
        a.info:hover {
                z-index: 25;
                color: #FFF; background-color: #900;
        }
        a.info span { display: none; }
        a.info:hover span.info {
                /* The span will display just on :hover state. */
                display: block;
                position: absolute;
                font-size: smaller;
                top: 2em; left: -5em; width: 15em;
                padding: 2px; border: 1px solid #333;
                color: #900; background-color: #EEE;
                text-align: left;
        }

        a { font-weight: bold; }
        a:link    { color: #900; background-color: transparent; }
        a:visited { color: #633; background-color: transparent; }
        a:active  { color: #633; background-color: transparent; }

        p { margin-left: 2em; margin-right: 2em; }
        p.copyright { font-size: x-small; }
        p.toc { font-size: small; font-weight: bold; margin-left: 3em; }
        table.toc { margin: 0 0 0 3em; padding: 0; border: 0; vertical-align: text-top; }
        td.toc { font-size: small; font-weight: bold; vertical-align: text-top; }

        ol.text { margin-left: 2em; margin-right: 2em; }
        ul.text { margin-left: 2em; margin-right: 2em; }
        li      { margin-left: 3em; }

        /* RFC-2629 <spanx>s and <artwork>s. */
        em     { font-style: italic; }
        strong { font-weight: bold; }
        dfn    { font-weight: bold; font-style: normal; }
        cite   { font-weight: normal; font-style: normal; }
        tt     { color: #036; }
        tt, pre, pre dfn, pre em, pre cite, pre span {
                font-family: "Courier New", Courier, monospace; font-size: small;
        }
        pre {
                text-align: left; padding: 4px;
                color: #000; background-color: #CCC;
        }
        pre dfn  { color: #900; }
        pre em   { color: #66F; background-color: #FFC; font-weight: normal; }
        pre .key { color: #33C; font-weight: bold; }
        pre .id  { color: #900; }
        pre .str { color: #000; background-color: #CFF; }
        pre .val { color: #066; }
        pre .rep { color: #909; }
        pre .oth { color: #000; background-color: #FCF; }
        pre .err { background-color: #FCC; }

        /* RFC-2629 <texttable>s. */
        table.all, table.full, table.headers, table.none {
                font-size: small; text-align: center; border-width: 2px;
                vertical-align: top; border-collapse: collapse;
        }
        table.all, table.full { border-style: solid; border-color: black; }
        table.headers, table.none { border-style: none; }
        th {
                font-weight: bold; border-color: black;
                border-width: 2px 2px 3px 2px;
        }
        table.all th, table.full th { border-style: solid; }
        table.headers th { border-style: none none solid none; }
        table.none th { border-style: none; }
        table.all td {
                border-style: solid; border-color: #333;
                border-width: 1px 2px;
        }
        table.full td, table.headers td, table.none td { border-style: none; }

        hr { height: 1px; }
        hr.insert {
                width: 80%; border-style: none; border-width: 0;
                color: #CCC; background-color: #CCC;
        }
--></style>
</head>
<body>
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<table summary="layout" width="66%" border="0" cellpadding="0" cellspacing="0"><tr><td><table summary="layout" width="100%" border="0" cellpadding="2" cellspacing="1">
<tr><td class="header">Implementers' Draft</td><td class="header">B. Eaton</td></tr>
<tr><td class="header">&nbsp;</td><td class="header">Google, Inc</td></tr>
<tr><td class="header">&nbsp;</td><td class="header">March 29, 2009</td></tr>
</table></td></tr></table>
<h1><br />OAuth Request Body Hash 1.0 Draft 5</h1>

<h3>Abstract</h3>

<p>
        This specification extends the OAuth signature to include
        integrity checks on HTTP request bodies with content types other than
        <tt>application/x-www-form-urlencoded</tt>.
      
</p><a name="toc"></a><br /><hr />
<h3>Table of Contents</h3>
<p class="toc">
<a href="#anchor1">1.</a>&nbsp;
Notation and Conventions<br />
<a href="#anchor2">2.</a>&nbsp;
Introduction<br />
<a href="#parameter">3.</a>&nbsp;
The oauth_body_hash Parameter<br />
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#anchor3">3.1.</a>&nbsp;
Hash Algorithm<br />
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#anchor4">3.2.</a>&nbsp;
Calculating the oauth_body_hash Parameter<br />
<a href="#anchor5">4.</a>&nbsp;
Additions to Request Signing<br />
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#when_to_include">4.1.</a>&nbsp;
When to Include the Body Hash<br />
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#anchor6">4.2.</a>&nbsp;
Adding oauth_body_hash to Requests<br />
<a href="#anchor7">5.</a>&nbsp;
Verifying Requests<br />
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#anchor8">5.1.</a>&nbsp;
When to Verify the Hash<br />
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#anchor9">5.2.</a>&nbsp;
Verifying the Hash<br />
<a href="#anchor10">6.</a>&nbsp;
Examples<br />
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#anchor11">6.1.</a>&nbsp;
Example PUT Request<br />
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#anchor12">6.2.</a>&nbsp;
Example GET Request<br />
<a href="#anchor13">7.</a>&nbsp;
Security Considerations<br />
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#anchor14">7.1.</a>&nbsp;
Only trust what is signed<br />
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#anchor15">7.2.</a>&nbsp;
Deprecation of SHA-1<br />
<a href="#anchor16">Appendix&nbsp;A.</a>&nbsp;
Obtaining the HTTP Entity Body<br />
<a href="#unkeyed">Appendix&nbsp;B.</a>&nbsp;
Unkeyed vs Keyed Hash Algorithms<br />
<a href="#removing_body">Appendix&nbsp;C.</a>&nbsp;
Preventing Removal of Request
    Bodies<br />
<a href="#rfc.references1">8.</a>&nbsp;
References<br />
<a href="#rfc.authors">&#167;</a>&nbsp;
Author's Address<br />
</p>
<br clear="all" />

<a name="anchor1"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.1"></a><h3>1.&nbsp;
Notation and Conventions</h3>

<p>
        The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
        "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
        document are to be interpreted as described in
        <a class='info' href='#RFC2119'>[RFC2119]<span> (</span><span class='info'>Bradner, B., &ldquo;Key words for use in RFCs to Indicate Requirement Levels,&rdquo; .</span><span>)</span></a>.
      
</p>
<p>
        Unless otherwise noted, this specification is written as a direct
        continuation of <a class='info' href='#OAuth Core 1.0'>[OAuth Core 1.0]<span> (</span><span class='info'>OAuth Core Workgroup, &ldquo;OAuth Core 1.0,&rdquo; .</span><span>)</span></a>, inheriting the
        definitions and guidelines set by it.
      
</p>
<a name="anchor2"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.2"></a><h3>2.&nbsp;
Introduction</h3>

<p>
        The OAuth Core specification <a class='info' href='#OAuth Core 1.0'>[OAuth Core 1.0]<span> (</span><span class='info'>OAuth Core Workgroup, &ldquo;OAuth Core 1.0,&rdquo; .</span><span>)</span></a> provides
        body integrity checking only for
        <tt>application/x-www-form-urlencoded</tt>
        request bodies.  Other types of request bodies are left unsigned.
        An eavesdropper or man-in-the-middle who captures a signed request URL
        may be able to forward or replay that URL with a different HTTP
        request body.  Nonce checking and the use of https can mitigate this
        risk, but may not be available in some environments.  Even when 
        nonce checking and https are used, signing the request body provides
        an additional layer of defense.
      
</p>
<p>
        This specification describes a method to provide an integrity check
        on non-form-encoded request bodies.  The normal OAuth signature
        base string is used by adding an additional parameter with the hash
        of the request body.  An unkeyed hash is used for the reasons
        described in
        <a class='info' href='#unkeyed'>Unkeyed vs Keyed Hash Algorithms<span> (</span><span class='info'>Unkeyed vs Keyed Hash Algorithms</span><span>)</span></a>.
      
</p>
<p>
        This extension is forward compatible: Service Providers
        that have not implemented this extension can verify requests
        sent by Consumers that have implemented this extension.
        If the Service Provider
        implements this specification the integrity of the body is guaranteed.
        If the Service Provider does not check body signatures, the remainder
        of the request will still validate using the OAuth Core signature
        algorithm.
      
</p>
<p>
        This specification is only useful when cryptographic signatures
        are used.  The OAuth PLAINTEXT signature algorithm does not provide
        integrity checks for any portion of the request and is not supported
        by this specification.
      
</p>
<a name="parameter"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.3"></a><h3>3.&nbsp;
The oauth_body_hash Parameter</h3>

<p>
        OAuth Consumers and Service Providers calculate the oauth_body_hash
        according to the following rules:
      
</p>
<a name="anchor3"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.3.1"></a><h3>3.1.&nbsp;
Hash Algorithm</h3>

<p>
          The body hash algorithm is determined by the OAuth signature
          method used.
        
</p>
<p>
          </p>
<ul class="text">
<li>
              If the OAuth signature method is HMAC-SHA1 or RSA-SHA1, SHA1
              <a class='info' href='#RFC3174'>[RFC3174]<span> (</span><span class='info'>Eastlake, 3rd, D. and P. Jones, &ldquo;US Secure Hash Algorithm 1 (SHA1),&rdquo; .</span><span>)</span></a> MUST be used as the body hash
              algorithm.
            
</li>
<li>
              If the OAuth signature method is PLAINTEXT, use of this
              specification provides no security benefit and is NOT
              RECOMMENDED.
            
</li>
</ul><p>
        
</p>
<p>
          New OAuth signature method specifications SHOULD specify the hash
          algorithm used to generate the body hash.
        
</p>
<a name="anchor4"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.3.2"></a><h3>3.2.&nbsp;
Calculating the oauth_body_hash Parameter</h3>

<p>
          The value of the oauth_body_hash parameter is obtained as follows:
        
</p>
<p>
          </p>
<ol class="text">
<li>
              Calculate the body hash value by executing the selected
              hash algorithm over the request body.  The request body is
              the entity body as defined in <a class='info' href='#RFC2616'>[RFC2616]<span> (</span><span class='info'>Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P., and T. Berners-Lee, &ldquo;Hypertext Transfer Protocol -- HTTP/1.1,&rdquo; .</span><span>)</span></a>
              section 7.2.  If the request does not have an entity body, the
              hash should be taken over the empty string.
            
</li>
<li>
              Base64 <a class='info' href='#RFC2045'>[RFC2045]<span> (</span><span class='info'>Freed, N. and N. Borenstein, &ldquo;Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies,&rdquo; .</span><span>)</span></a> encode the hash value.
            
</li>
</ol><p>
        
</p>
<a name="anchor5"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.4"></a><h3>4.&nbsp;
Additions to Request Signing</h3>

<p>
        OAuth Consumers implementing this specification continue to sign
        requests in the manner described by OAuth Core.  They also
        include the oauth_body_hash parameter according to the rules
        described in this section.
      
</p>
<a name="when_to_include"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.4.1"></a><h3>4.1.&nbsp;
When to Include the Body Hash</h3>

<p>
          Not all requests should contain the oauth_body_hash parameter.
        
</p>
<p>
          OAuth Consumers SHOULD NOT include an oauth_body_hash parameter on 
          OAuth request token and access token requests.  Some OAuth Service
          Providers have implemented request token and access token endpoints
          that reject requests that include unknown parameters.  Sending
          an oauth_body_hash parameter to such endpoints will cause protocol
          failures.  The oauth_body_hash parameter does not provide additional
          security for OAuth request and access token requests since all of 
          the protocol parameters are signed by the OAuth Core signature
          mechanism.  Omitting the parameter improves interoperability without
          reducing security.
        
</p>
<p>
          OAuth Consumers MUST NOT include an oauth_body_hash parameter on
          requests with form-encoded request bodies.  The presence or absence
          of the oauth_body_hash parameter is used to indicate to Service
          Providers how they should check the integrity of the request body.
          If no oauth_body_hash parameter is present, that indicates that
          the request body is form-encoded and signed using the OAuth Core
          signature algorithm.  If the oauth_body_hash parameter is present,
          the body is signed according to this extension.  Including
          an oauth_body_hash on form-encoded requests would make it impossible
          for Service Providers to determine which body signing mechanism
          was used for the request.  This ambiguity would, in turn, allow
          the attack described in <a class='info' href='#removing_body'>Preventing Removal of Request Bodies<span> (</span><span class='info'>Preventing Removal of Request     Bodies</span><span>)</span></a>.
        
</p>
<p>
          OAuth Consumers SHOULD include the oauth_body_hash parameter on all
          other requests.
        
</p>
<a name="anchor6"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.4.2"></a><h3>4.2.&nbsp;
Adding oauth_body_hash to Requests</h3>

<p>
          OAuth Consumers use the following procedure to add
          oauth_body_hash to requests:
          </p>
<ol class="text">
<li>
              Determine whether the parameter should be sent at all, using
              the rules described in <a class='info' href='#when_to_include'>When to Include the Body Hash<span> (</span><span class='info'>When to Include the Body Hash</span><span>)</span></a>.
            
</li>
<li>
              Calculate the body hash value as described in 
              <a class='info' href='#parameter'>The oauth_body_hash Parameter<span> (</span><span class='info'>The oauth_body_hash Parameter</span><span>)</span></a>.
            
</li>
<li>
              Set the oauth_body_hash parameter to the obtained value.
            
</li>
<li>
              Sign the request as per section 9 "Signing Requests" of
              <a class='info' href='#OAuth Core 1.0'>[OAuth Core 1.0]<span> (</span><span class='info'>OAuth Core Workgroup, &ldquo;OAuth Core 1.0,&rdquo; .</span><span>)</span></a>.
              The oauth_body_hash parameter MUST be
              included in the Signature Base String together with the
              other request parameters.
            
</li>
<li>
              Include the oauth_body_hash parameter along with the other
              OAuth Protocol parameters in the signed OAuth request.
            
</li>
</ol><p>
        
</p>
<a name="anchor7"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.5"></a><h3>5.&nbsp;
Verifying Requests</h3>

<p>
        Service Providers verify the integrity of request bodies
        by verifying the OAuth signature as described in
        <a class='info' href='#OAuth Core 1.0'>[OAuth Core 1.0]<span> (</span><span class='info'>OAuth Core Workgroup, &ldquo;OAuth Core 1.0,&rdquo; .</span><span>)</span></a> and also verifying the value of the
        oauth_body_hash parameter.
      
</p>
<a name="anchor8"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.5.1"></a><h3>5.1.&nbsp;
When to Verify the Hash</h3>

<p>
          Service Providers SHOULD decide whether the oauth_body_hash parameter
          is necessary according to the rules described in
          <a class='info' href='#when_to_include'>When to Include the Body Hash<span> (</span><span class='info'>When to Include the Body Hash</span><span>)</span></a>.
        
</p>
<p>
          If the request must not have an oauth_body_hash parameter,
          Service Providers MUST verify that no oauth_body_hash parameter is
          present.
          In particular, any requests with a form-encoded content-type
          and an oauth_body_hash parameter MUST be rejected because of
          of the attack described in <a class='info' href='#removing_body'>Preventing Removal of Request Bodies<span> (</span><span class='info'>Preventing Removal of Request     Bodies</span><span>)</span></a>.
        
</p>
<p>
          If the request should have an oauth_body_hash parameter
          but does not contain one, the request was sent by a
          Consumer that does not support this extension.  The integrity
          of the request body cannot be checked using this specification.
          Service Providers MAY accept such requests for interoperability,
          or they MAY reject such requests in favor of security.
        
</p>
<a name="anchor9"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.5.2"></a><h3>5.2.&nbsp;
Verifying the Hash</h3>

<p>
          If the Service Provider determines body hash verification is
          necessary, the Service Provider calculates the expected
          body hash for the request as described in
          <a class='info' href='#parameter'>The oauth_body_hash Parameter<span> (</span><span class='info'>The oauth_body_hash Parameter</span><span>)</span></a>.
        
</p>
<p>
          The Service Provider then compares the expected body hash with
          the value sent by the Consumer in the oauth_body_hash parameter.
          If the values match, the body is intact and the request can
          proceed.
        
</p>
<p>
          If the values do not match, the request MUST be rejected.
        
</p>
<p>
          Rather than comparing text values, Service Providers MAY
          Base64 decode the oauth_body_hash parameter and perform the
          comparison on the octets of the hash.  This reduces the risk of
          minor differences in URL encoding or Base64 encoding causing
          spurious integrity check failures.
        
</p>
<a name="anchor10"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.6"></a><h3>6.&nbsp;
Examples</h3>

<a name="anchor11"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.6.1"></a><h3>6.1.&nbsp;
Example PUT Request</h3>

<p>
          Sample HTTP request:
          </p>
<div style='display: table; width: 0; margin-left: 3em; margin-right: auto'><pre>
    PUT /resource HTTP/1.1
    Host: www.example.com
    Content-Type: text/plain
    Content-Length: 12

    Hello World!
</pre></div><p>

        
</p>
<p>
          Base64 encoded SHA-1 hash of the body:
          </p>
<div style='display: table; width: 0; margin-left: 3em; margin-right: auto'><pre>
    Lve95gjOVATpfV8EL5X4nxwjKHE=
</pre></div><p>

        
</p>
<p>
          Signature Base String (with some line breaks added for
          readability):
          </p>
<div style='display: table; width: 0; margin-left: 3em; margin-right: auto'><pre>
    PUT&amp;http%3A%2F%2Fwww.example.com%2Fresource&amp;oauth_body_hash%3D
    Lve95gjOVATpfV8EL5X4nxwjKHE%253D%26oauth_consumer_key%3Dconsum
    er%26oauth_nonce%3D10369470270925%26oauth_signature_method%3DH
    MAC-SHA1%26oauth_timestamp%3D1236874236%26oauth_token%3Dtoken%
    26oauth_version%3D1.0
</pre></div><p>

        
</p>
<p>
          Signed request with body hash (with some line breaks added for
          readability):
          </p>
<div style='display: table; width: 0; margin-left: 3em; margin-right: auto'><pre>
    PUT /resource HTTP/1.1
    Host: www.example.com
    Authorization: OAuth realm="http%3A%2F%2Fwww.example.com",
        oauth_body_hash="Lve95gjOVATpfV8EL5X4nxwjKHE%3D",
        oauth_token="token",
        oauth_consumer_key="consumer",
        oauth_signature_method="HMAC-SHA1",
        oauth_timestamp="1236874155", oauth_nonce="10288510250934",
        oauth_version="1.0",
        oauth_signature="08bUFF%2Fjmp59mWB7cSgCYBUpJ0U%3D"
    Content-Type: text/plain
    Content-Length: 12

    Hello World!
</pre></div><p>

        
</p>
<a name="anchor12"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.6.2"></a><h3>6.2.&nbsp;
Example GET Request</h3>

<p>
          Sample HTTP request:
          </p>
<div style='display: table; width: 0; margin-left: 3em; margin-right: auto'><pre>
    GET /resource HTTP/1.1
    Host: www.example.com

</pre></div><p>

        
</p>
<p>
          Base64 encoded SHA-1 hash of the (non-existent) body:
          </p>
<div style='display: table; width: 0; margin-left: 3em; margin-right: auto'><pre>
    2jmj7l5rSw0yVb/vlWAYkK/YBwk=
</pre></div><p>

        
</p>
<p>
          Signature Base String (with some line breaks added for
          readability):
          </p>
<div style='display: table; width: 0; margin-left: 3em; margin-right: auto'><pre>
    GET&amp;http%3A%2F%2Fwww.example.com%2Fresource&amp;oauth_body_hash%3D
    2jmj7l5rSw0yVb%252FvlWAYkK%252FYBwk%253D%26oauth_consumer_key%3Dconsum
    er%26oauth_nonce%3D8628868109991%26oauth_signature_method%3DHMAC-SHA1%
    26oauth_timestamp%3D1238395022%26oauth_token%3Dtoken%26oauth_version%3
    D1.0
</pre></div><p>

        
</p>
<p>
          Signed request with body hash (with some line breaks added for
          readability):
          </p>
<div style='display: table; width: 0; margin-left: 3em; margin-right: auto'><pre>
    GET /resource HTTP/1.1
    Host: www.example.com
    Authorization: OAuth realm="http%3A%2F%2Fwww.example.com",
        oauth_body_hash="2jmj7l5rSw0yVb/vlWAYkK/YBwk%3D",
        oauth_token="token",
        oauth_consumer_key="consumer",
        oauth_signature_method="HMAC-SHA1",
        oauth_timestamp="1236874155", oauth_nonce="10288510250934",
        oauth_version="1.0",
        oauth_signature="08bUFF%2Fjmp59mWB7cSgCYBUpJ0U%3D"
</pre></div><p>

        
</p>
<a name="anchor13"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.7"></a><h3>7.&nbsp;
Security Considerations</h3>

<a name="anchor14"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.7.1"></a><h3>7.1.&nbsp;
Only trust what is signed</h3>

<p>
          Many factors besides the bytes of the request body can
          influence the interpretation of the body of the HTTP
          request.  For example, a content-type or content-encoding
          header can change the way a server handles an HTTP request.
          This specification does not include an integrity check
          on the HTTP request headers.  OAuth deployments whose
          security could be impacted by an attacker who tampers with
          HTTP request headers should use other mechanisms (such as HTTPS)
          to protect the confidentiality and integrity of the entire HTTP
          request.
        
</p>
<a name="anchor15"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.7.2"></a><h3>7.2.&nbsp;
Deprecation of SHA-1</h3>

<p>
          The NIST Computer Security Division has recommended that applications
          <a class='info' href='#NIST 800-107'>stop using SHA-1 for digital signatures<span> (</span><span class='info'>Dang, Q., &ldquo;Special Publication 800-107, Recommendation for Applications Using Approved Hash Algorithms,&rdquo; .</span><span>)</span></a> [NIST 800&#8209;107].  As of the time
          of this writing, all of the cryptographic signature schemes defined
          for OAuth are based on SHA-1.  OAuth signature methods based on
          stronger hash functions need to be developed, and those signature
          methods will need to specify algorithms for calculating the
          oauth_body_hash as well.
        
</p>
<a name="anchor16"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.A"></a><h3>Appendix A.&nbsp;
Obtaining the HTTP Entity Body</h3>

<p>
        Not all programming platforms provide an easy mechanism to obtain
        the raw octets of the HTTP entity body.  Reading the entity body
        as raw octets may have side effects, such as inhibiting automatic
        character set conversion.  Transfer-encodings such as gzip
        also complicate implementation.  On the other hand,
        reading the entity body as text may perform lossy conversions
        that prevent recovery of the original octet stream in some
        situtations.  Character set conversions are not always one-to-one
        mappings, so solutions that rely on converting text back to the
        original octet stream are likely to fail in environments with
        multibyte characters.
      
</p>
<p>
        All of these factors, and others, can make it difficult to drop in a
        "verify-the-signature" filtering layer prior to other request
        processing.  The verification layer must consider the assumptions
        of downstream processing code on the state of the request body.
      
</p>
<p>
        Implementers of this specification should be aware of these
        difficulties and consider the best way to address them in their
        programming frameworks.
      
</p>
<a name="unkeyed"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.B"></a><h3>Appendix B.&nbsp;
Unkeyed vs Keyed Hash Algorithms</h3>

<p>
        This specification deliberately uses an unkeyed hash algorithm
        (SHA-1) to provide an integrity check on the body instead of
        a keyed hash algorithm such as HMAC-SHA1.  This decision was made
        because signing arbitrary octet streams is poor cryptographic hygiene.
        It can lead to unexpected problems with cryptographic protocols.
      
</p>
<p>
        For example, consider a proxy that uses OAuth to add authentication
        information to requests sent by an untrusted third-party.  If the
        proxy signs arbitrary octet streams, the third-party can use the
        proxy as an oracle to forge authentication messages.
      
</p>
<p>
        Including the result of an unkeyed hash in the normal signature 
        base string allows the proxy to add an integrity check on the
        original message without creating a signing oracle.
      
</p>
<a name="removing_body"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.C"></a><h3>Appendix C.&nbsp;
Preventing Removal of Request
    Bodies</h3>

<p>
        This specification requires that Consumers not send the oauth_body_hash
        parameter on requests with form-encoded bodies, and requires that
        Service Providers reject requests that have form-encoded bodies
        and an oauth_body_hash parameter.  These restrictions are necessary
        in order to prevent a MITM from removing non-form-encoded request
        bodies.  The attack would work as follows:
      
</p>
<p>
        </p>
<ol class="text">
<li>
            Consumer signs a request with a non-form-encoded request body
            and includes a matching content-type header such as
            "application/json" or "text/plain".  The oauth_body_hash parameter
            is included as well.
          
</li>
<li>
            MITM intercepts request and modifies the content-type of the
            request to be "application/x-www-form-urlencoded".  The MITM
            also removes the request body.  The request is then forwarded
            to the Service Provider.
          
</li>
<li>
            The Service Provider receives the request and the signature
            validates according to the OAuth Core signature specification.
          
</li>
<li>
            The Service Provider then needs to decide whether to check
            the oauth_body_hash value as well.  Since the request content-type
            is form-encoded, the Service Provider does not check the
            oauth_body_hash.
          
</li>
<li>
            The removal of the body goes undetected.  
          
</li>
</ol><p>
      
</p>
<p>
        The impact of this attack is probably minimal.  The attacker can
        remove the request body, but cannot replace it with their own.  Stil,
        the goal of this specification is guaranteeing body integrity
        when both Consumers and Service Providers use the oauth_body_hash
        parameter.  Out of an excess of caution, this specification requires
        that Service Providers reject request that have both a form-encoded
        request body and an oauth_body_hash parameter.
      
</p>
<p>
        An alternate solution, requiring that Service Providers check the
        oauth_body_hash parameter even on form-encoded request bodies, was
        rejected due to implementation challenges.  Some web development
        frameworks block access to the raw entity body for form-encoded
        requests.
      
</p>
<a name="rfc.references1"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<h3>8.&nbsp;References</h3>
<table width="99%" border="0">
<tr><td class="author-text" valign="top"><a name="NIST 800-107">[NIST 800-107]</a></td>
<td class="author-text">Dang, Q., &ldquo;<a href="http://csrc.nist.gov/publications/nistpubs/800-107/NIST-SP-800-107.pdf">Special Publication 800-107, Recommendation for Applications Using Approved Hash Algorithms</a>.&rdquo;</td></tr>
<tr><td class="author-text" valign="top"><a name="OAuth Core 1.0">[OAuth Core 1.0]</a></td>
<td class="author-text">OAuth Core Workgroup, &ldquo;<a href="http://oauth.net/core/1.0">OAuth Core 1.0</a>.&rdquo;</td></tr>
<tr><td class="author-text" valign="top"><a name="RFC2045">[RFC2045]</a></td>
<td class="author-text">Freed, N. and N. Borenstein, &ldquo;<a href="http://tools.ietf.org/html/rfc2045">Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies</a>,&rdquo; RFC&nbsp;2045.</td></tr>
<tr><td class="author-text" valign="top"><a name="RFC2119">[RFC2119]</a></td>
<td class="author-text">Bradner, B., &ldquo;<a href="http://tools.ietf.org/html/rfc2119">Key words for use in RFCs to Indicate Requirement Levels</a>,&rdquo; RFC&nbsp;2119.</td></tr>
<tr><td class="author-text" valign="top"><a name="RFC2616">[RFC2616]</a></td>
<td class="author-text">Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P., and T. Berners-Lee, &ldquo;<a href="http://tools.ietf.org/html/rfc2616">Hypertext Transfer Protocol -- HTTP/1.1</a>,&rdquo; RFC&nbsp;2616.</td></tr>
<tr><td class="author-text" valign="top"><a name="RFC3174">[RFC3174]</a></td>
<td class="author-text">Eastlake, 3rd, D. and P. Jones, &ldquo;<a href="http://tools.ietf.org/html/rfc3174">US Secure Hash Algorithm 1 (SHA1)</a>,&rdquo; RFC&nbsp;3174.</td></tr>
</table>

<a name="rfc.authors"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<h3>Author's Address</h3>
<table width="99%" border="0" cellpadding="0" cellspacing="0">
<tr><td class="author-text">&nbsp;</td>
<td class="author-text">Brian Eaton</td></tr>
<tr><td class="author-text">&nbsp;</td>
<td class="author-text">Google, Inc</td></tr>
<tr><td class="author" align="right">Email:&nbsp;</td>
<td class="author-text"><a href="mailto:beaton@google.com">beaton@google.com</a></td></tr>
</table>
</body></html>
